package me.lensfrex.trailblazer.api.v1.service.login;

import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import me.lensfrex.trailblazer.api.v1.beans.requests.LoginRequestBody;
import me.lensfrex.trailblazer.api.v1.beans.responses.LoginResponseData;
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ErrorResponse;
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ResponseBase;
import me.lensfrex.trailblazer.api.v1.beans.responses.general.ResponseCode;
import me.lensfrex.trailblazer.api.v1.exceptions.user.LoginInfoWrongException;
import me.lensfrex.trailblazer.api.v1.pojos.UserInformation;
import me.lensfrex.trailblazer.api.v1.utils.InputChecker;
import me.lensfrex.trailblazer.api.v1.dao.UserDao;
import me.lensfrex.trailblazer.api.v1.utils.jwt.JWTManager;
import org.mindrot.jbcrypt.BCrypt;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;

@Path("/login")
public class Login {
    private static final Gson gson = new Gson();
    private static final JWTManager jwtManager = JWTManager.getInstance();

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String login(String request) {
        LoginRequestBody loginRequestBody;
        try {
            loginRequestBody = gson.fromJson(request, LoginRequestBody.class);
            if (InputChecker.hasInvalidChar(loginRequestBody.getUserName()) ||
                    InputChecker.hasInvisibleChar(loginRequestBody.getPassword())) {
                ErrorResponse errorResponse = new ErrorResponse(100, "请求的用户名或密码非法");

                return gson.toJson(errorResponse);
            }

            UserInformation userDatabaseInformation = UserDao.getUser(loginRequestBody.getUserName());

            if (userDatabaseInformation == null) {
                throw new LoginInfoWrongException();
            }

            if (!identifyPassword(loginRequestBody.getPassword(), userDatabaseInformation.password)) {
                throw new LoginInfoWrongException();
            }

            Date expireDate = Date.from(Instant.now().plus(JWTManager.TOKEN_DEFAULT_EXPIRE_DAY, ChronoUnit.DAYS));
            String userToken = jwtManager.createNewJWT(loginRequestBody.getUserName(), expireDate);

            LoginResponseData loginResponseData = new LoginResponseData(
                    userDatabaseInformation.uid,
                    userDatabaseInformation.uuid,
                    userDatabaseInformation.accountStatus,
                    userToken,
                    expireDate.getTime());

            ResponseBase<LoginResponseData> response = ResponseBase.success(loginResponseData);

            return gson.toJson(response);
        } catch (JsonParseException e) {
            return gson.toJson(ResponseBase.error(ResponseCode.REQUEST_FORMAT_INVALID, "请求的数据格式不对"));
        } catch (LoginInfoWrongException e) {
            return gson.toJson(ResponseBase.error(ResponseCode.PASSWORD_WRONG, "用户名或密码错误"));
        } catch (Exception e) {
            return gson.toJson(ResponseBase.error(ResponseCode.SERVER_ERROR, "服务器内部错误，请联系那个背锅的家伙"));
        }
    }

    public boolean identifyPassword(String originPassword, String bcryptPassword) {
        return BCrypt.checkpw(originPassword, bcryptPassword);
    }
}